import unittest
from Memory.Memoria import Memoria
from Memory.ContinuosAsignment.MMU import MMU
from SistemaOperativo.Instruction import Instruction, CpuInstruction
from Memory.Celda import Celda
from Memory.ContinuosAsignment.Gap import Gap
from Memory.Programa import Programa
from SistemaOperativo.PCB import PCB


class AssigmentTest(unittest.TestCase):


    def testMemoryIsFull(self):
        memory = Memoria(3)
        mmu = MMU(memory, None)
        
        inst1 = Instruction()
        celda1 = Celda(0)
        celda1.instruction = inst1
        celda2 = Celda(1)
        celda2.instruction = inst1
        celda3 = Celda(2)
        celda3.instruction = inst1
        
        memory.getList().insert(0, celda1)
        memory.getList().insert(1, celda2)
        memory.getList().insert(2, celda3)
        
        self.assertTrue(mmu.memoryIsFull())
        
    def testCompact(self):
        gap1 = Gap(2)
        gap2 = Gap(5)
        gap3 = Gap(3)
        
        memory = Memoria(3)
        mmu = MMU(memory, None)
        
        mmu.gaps = []
        mmu.gaps.append(gap1)
        mmu.gaps.append(gap2)
        mmu.gaps.append(gap3)
        
        mmu.compact()
        
        self.assertTrue(len(mmu.gaps) == 1)
        self.assertTrue(mmu.gaps.pop().size == 10)
        
    def testIsLast(self):
        prog1 = Programa("1")
        prog2 = Programa("2")
        prog3 = Programa("3")
        
        memory = Memoria(3)
        mmu = MMU(memory, None)
        
        mmu.programs.append(prog1)
        mmu.programs.append(prog2)
        mmu.programs.append(prog3)
        mmu.programs.remove(prog3)
        #self.assertTrue(mmu.isLast(prog3))
        self.assertTrue(mmu.isLast(prog2))
        
    def testReturnBlockPrimerAjuste(self):
        gap1 = Gap(5)
        gap2 = Gap(4)
        gap3 = Gap(6)
        gap4 = Gap(5)
        gap5 = Gap(6)
        gap6 = Gap(2)
        gap7 = Gap(3)
        
        memory = Memoria(10)
        mmu = MMU(memory, None)
        
        mmu.gaps = []
        mmu.gaps.append(gap1)
        mmu.gaps.append(gap2)
        mmu.gaps.append(gap3)
        mmu.gaps.append(gap4)
        mmu.gaps.append(gap5)
        mmu.gaps.append(gap6)
        mmu.gaps.append(gap7)
        
        self.assertTrue(mmu.returnBlockPrimerAjuste(6) == gap3)
        
    def testReturnBlockMejorAjuste(self):
        gap1 = Gap(5)
        gap2 = Gap(4)
        gap3 = Gap(6)
        gap4 = Gap(5)
        gap5 = Gap(6)
        gap6 = Gap(2)
        gap7 = Gap(3)
        
        memory = Memoria(10)
        mmu = MMU(memory, None)
        
        mmu.gaps = []
        mmu.gaps.append(gap1)
        mmu.gaps.append(gap2)
        mmu.gaps.append(gap3)
        mmu.gaps.append(gap4)
        mmu.gaps.append(gap5)
        mmu.gaps.append(gap6)
        mmu.gaps.append(gap7)
        
        self.assertTrue(mmu.returnBlockMejorAjuste(6) == gap3)
        self.assertTrue(mmu.returnBlockMejorAjuste(5) == gap1)
        self.assertTrue(mmu.returnBlockMejorAjuste(2) == gap6)
        
    def testReturBlockPeorAjuste(self):
        gap1 = Gap(5)
        gap2 = Gap(4)
        gap3 = Gap(6)
        gap4 = Gap(5)
        gap5 = Gap(6)
        gap6 = Gap(2)
        gap7 = Gap(3)
        
        memory = Memoria(10)
        mmu = MMU(memory, None)
        
        mmu.gaps = []
        mmu.gaps.append(gap1)
        mmu.gaps.append(gap2)
        mmu.gaps.append(gap3)
        mmu.gaps.append(gap4)
        mmu.gaps.append(gap5)
        mmu.gaps.append(gap6)
        mmu.gaps.append(gap7)
        
        self.assertTrue(mmu.returnBlockPeorAjuste(1) == gap3)
        self.assertTrue(mmu.returnBlockPeorAjuste(4) == gap3)
        
    def testSwappIn(self):
        memory = Memoria(10)
        mmu = MMU(memory, None)
        pcb = PCB(123, 0, 2)
        pcb.baseRegistry = 0
        
        inst1 = CpuInstruction(1)
        inst2 = CpuInstruction(1)
        inst3 = CpuInstruction(2)
        inst4 = CpuInstruction(3)
        
        instructionList = []
        instructionList.append(inst1)
        instructionList.append(inst2)
        instructionList.append(inst3)
        instructionList.append(inst4)
        
        prog1 = Programa(instructionList, "1")
        
        mmu.swappIn(prog1, pcb)
        
        self.assertTrue(memory.countFullCells() == 4)
        self.assertTrue(memory.countEmptyCells() == 6)
        
    def testSwappIn2Programs(self):
        memory = Memoria(10)
        mmu = MMU(memory, None)
        pcb = PCB(123, 0, 2)
        pcb2 = PCB(125, 0, 2)
        pcb.baseRegistry = 0
        
        inst1 = CpuInstruction(1)
        inst2 = CpuInstruction(1)
        inst3 = CpuInstruction(2)
        inst4 = CpuInstruction(3)
        
        instructionList1 = []
        instructionList2 = []
        
        instructionList1.append(inst1)
        instructionList1.append(inst2)
        
        instructionList2.append(inst3)
        instructionList2.append(inst4)
        
        prog1 = Programa(instructionList1, "1")
        prog2 = Programa(instructionList2, "2")
                
        mmu.swappIn(prog1, pcb)
        mmu.swappIn(prog2, pcb2)
        
        print(memory.countEmptyCells())
        print(memory.countFullCells())
        
        self.assertTrue(memory.countFullCells() == 4)
        self.assertTrue(memory.countEmptyCells() == 6)
        
    def testSwappOut(self):
        memory = Memoria(10)
        mmu = MMU(memory, None)
        pcb = PCB(123, 0, 2)
        pcb.baseRegistry = 0
        
        inst1 = CpuInstruction(1)
        inst2 = CpuInstruction(1)
        inst3 = CpuInstruction(2)
        inst4 = CpuInstruction(3)
        
        instructionList = []
        instructionList.append(inst1)
        instructionList.append(inst2)
        instructionList.append(inst3)
        instructionList.append(inst4)
        
        prog1 = Programa(instructionList, "1")
        
        mmu.swappIn(prog1, pcb)
        
        mmu.swappOut(prog1, pcb)
        
        self.assertTrue(memory.countFullCells() == 0)
        self.assertTrue(memory.countEmptyCells() == memory.getLength())
        
    def testPositionContEmptyCells(self):
        memory = Memoria(10)
        mmu = MMU(memory, None)
        
        inst1 = Instruction(1)
        inst2 = Instruction(2)
        inst3 = Instruction(1)
        inst4 = Instruction(3)
        inst5 = Instruction(4)
        
        memory.list.__getitem__(0).instruction = inst1
        memory.list.__getitem__(1).instruction = inst2
        memory.list.__getitem__(2).instruction = inst3
        memory.list.__getitem__(3).instruction = inst4
        memory.list.__getitem__(4).instruction = inst5
        
        memory.list.__getitem__(1).instruction = None
        memory.list.__getitem__(2).instruction = None
        

        self.assertTrue(mmu.positionContEmptyCells(2) == 1)
        self.assertTrue(mmu.positionContEmptyCells(3) == 5)
        

    


  
suite = unittest.TestLoader().loadTestsFromTestCase(AssigmentTest)
unittest.TextTestRunner(verbosity=2).run(suite)